package com.lzy.cloud.ticket.train.facade;

import com.lzy.cloud.ticket.train.constant.LMMApi;
import com.lzy.cloud.ticket.train.constant.LMMContant;
import com.lzy.cloud.ticket.train.dtos.TrainChangsDto;
import com.lzy.cloud.ticket.train.dtos.TrainExpressInfoDto;
import com.lzy.cloud.ticket.train.dtos.TrainOrderDto;
import com.lzy.cloud.ticket.train.dtos.TrainPassengerDto;
import com.lzy.cloud.ticket.train.remote.OrderApi;
import com.lzy.cloud.ticket.train.remote.request.OrderInfoRequest;
import com.lzy.cloud.ticket.train.request.*;
import com.lzy.cloud.ticket.train.request.app.*;
import com.lzy.cloud.ticket.train.response.BaseResponse;
import com.lzy.cloud.ticket.train.response.OrderDetailResponse;
import com.lzy.cloud.ticket.train.response.SearchResponse;
import com.lzy.cloud.ticket.train.servcie.*;
import com.lzy.cloud.ticket.train.util.BasePushUtil;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.output.Result;
import com.lzy.framework.core.utils.DozerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static com.lzy.cloud.ticket.train.facade.TrainOrderFacade.belongCalendar;

@Component
public class OrderFacade {

    @Resource
    private RestTemplate restTemplate;

    @Autowired
    private BasePushUtil basePushUtil;

    @Autowired
    private TrainChangsService trainChangsService;

    @Autowired
    private TrainOrderService trainOrderService;

    @Autowired
    private TrainInsuranceService trainInsuranceService;

    @Autowired
    private TrainExpressInfoService trainExpressInfoService;

    @Autowired
    private TrainPassengerService trainPassengerService;

    @Autowired
    private OrderApi orderApi;

    /**
     * 预订订单
     * @param
     * @return
     */
    public Result bookingOrder(Long userId,OrderBookingAppRequest orderBookingAppRequest){
        Result result1 = insertOrder(userId, orderBookingAppRequest);
        if (result1 != null) return result1;

        //请求接口
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.BOOKING_ORDER_METHOD,LMMContant.MESSAGE_FORMT,LMMContant.CALL_BACK_URL+LMMContant.BOOKING_ORDER_CALL_BACK_URL);
        BookingOrderRequest bookingOrderRequest = DozerUtils.map(baseRequest,BookingOrderRequest.class);
        bookingOrderRequest.setData(orderBookingAppRequest);
        BaseResponse response = restTemplate.postForObject(LMMApi.BOOKING_ORDER_URL,bookingOrderRequest,SearchResponse.class);
        Result result = new Result();
        result.setCode(response.getCode());
        result.setDesc(response.getMessage());
        return result;
    }

    /**
     * 抢票
     * @param userId
     * @param orderBookingAppRequest
     * @return
     */
    public Result bookGrabOrder(Long userId,OrderBookingAppRequest orderBookingAppRequest){
        Result result1 = insertOrder(userId, orderBookingAppRequest);
        if (result1 != null) return result1;

        BookGrabOrderAppRequest bookGrabOrderAppRequest = DozerUtils.map(orderBookingAppRequest,BookGrabOrderAppRequest.class);
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.BOOK_GRAB_ORDER_METHOD,LMMContant.MESSAGE_FORMT,LMMContant.BOOK_GRAB_ORDER_CALL_BACK_URL);
        BookGrabOrderRequest bookGrabOrderRequest = DozerUtils.map(baseRequest,BookGrabOrderRequest.class);
        bookGrabOrderRequest.setData(bookGrabOrderAppRequest);
        BaseResponse response = restTemplate.postForObject(LMMApi.BOOK_GRAB_ORDER_URL,bookGrabOrderRequest,BaseResponse.class);
        Result result = new Result();
        result.setCode(response.getCode());
        result.setDesc(response.getMessage());
        return result;
    }

    private Result insertOrder(Long userId, OrderBookingAppRequest orderBookingAppRequest) {
        // TODO 现在为非正式单
        orderBookingAppRequest.getOrderBookingInfo().setIsFormalOrder(2);
        //数据库创建记录
        orderBookingAppRequest.getOrderBookingInfo().setSeatCode(basePushUtil.getPinYinHeadChar(orderBookingAppRequest.getOrderBookingInfo().getSeatName()));
        TrainOrderDto trainOrderDto = requestToDto(orderBookingAppRequest);

        trainOrderDto.setStatus(0);
        if (null == trainOrderDto.getCustomId()){
            trainOrderDto.setCustomId(userId+System.currentTimeMillis()+"");
        }

        //判断下单时间是否在可以预定时间内
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");//设置日期格式
        Date nowTime = null;
        try {
            nowTime = df.parse(df.format(new Date()));
            Date beginTime = df.parse("06:00");
            Date endTime = df.parse("23:00");
            Ensure.that(belongCalendar(nowTime, beginTime, endTime)).isTrue("00010007");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //判断未成年人不能单独买票
        if (null != trainOrderDto.getOrderBookingPassengerInfos() && trainOrderDto.getOrderBookingPassengerInfos().size() == 1) {
            if(trainOrderDto.getOrderBookingPassengerInfos().get(0).getPassengerType() == 2){
                Result result = new Result();
                result.setCode("-1");
                result.setDesc("未成年人不能单独买票");
                return result;
            }
        }
        long trainOrderId = trainOrderService.createTrainOrder(trainOrderDto);
        //保险信息新增
        /*for (TrainPassengerDto trainPassengerDto:trainOrderDto.getOrderBookingPassengerVos()) {
            if (trainPassengerDto.getInsuranceVos() != null && trainPassengerDto.getInsuranceVos().size() > 0) {
                for (TrainInsuranceDto trainInsuranceDto : trainPassengerDto.getInsuranceVos()) {
                    trainInsuranceDto.setInsuranceNo(trainOrderId);
                    trainInsuranceService.createTrainInsurance(trainInsuranceDto);
                }

            }
        }*/

        //物流信息新增
        if (trainOrderDto.getExpressInfo() != null) {
            TrainExpressInfoDto trainExpressInfo = trainOrderDto.getExpressInfo();
            trainExpressInfo.setTrainOrderId(trainOrderId);
            trainExpressInfoService.createTrainExpressInfo(trainExpressInfo);
        }

        //乘客信息新增
        if (null != trainOrderDto.getOrderBookingPassengerInfos() && trainOrderDto.getOrderBookingPassengerInfos().size() > 0) {
            for (TrainPassengerDto trainPassengerDto : trainOrderDto.getOrderBookingPassengerInfos()) {
                trainPassengerDto.setTrainOrderId(trainOrderId);
                trainPassengerService.createTrainPassenger(trainPassengerDto);
            }
        }
        return null;
    }

    /**
     * 取消订单
     * @param orderCancelAppRequest
     * @return
     */
    public Result cancelOrder(OrderCancelAppRequest orderCancelAppRequest){
        //从订单总表中取消订单
        OrderInfoRequest orderInfoRequest = new OrderInfoRequest();
        orderInfoRequest.setOrderId(orderCancelAppRequest.getOrderNo());
        Result cancel = orderApi.cancel(null,orderInfoRequest.getOrderId());
        if ("0" != cancel.getCode()){
            return cancel;
        }

        //修改train

        //请求接口
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.CANCEL_ORDER_METHOD,LMMContant.MESSAGE_FORMT,LMMContant.CALL_BACK_URL+LMMContant.CANCEL_ORDER_CALL_BACK_URL);
        CancelOrderRequest cancelOrderRequest = DozerUtils.map(baseRequest,CancelOrderRequest.class);
        cancelOrderRequest.setData(orderCancelAppRequest);
        BaseResponse response = restTemplate.postForObject(LMMApi.CANCEL_ORDER_URL,cancelOrderRequest,BaseResponse.class);

        Result result = new Result();
        result.setCode(response.getCode());
        result.setDesc(response.getMessage());
        return result;
    }

    /**
     * 确认出票
     * @param confirmTicketAppRequest
     * @return
     */
    public BaseResponse confirmTicket(ConfirmTicketAppRequest confirmTicketAppRequest){
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.CONFIRM_TICKET_METHOD,LMMContant.MESSAGE_FORMT,LMMContant.CALL_BACK_URL+LMMContant.CONFIRM_TICKET_CALL_BACK_URL);
        ConfirmTicketRequest confirmTicketRequest = DozerUtils.map(baseRequest,ConfirmTicketRequest.class);
        confirmTicketRequest.setData(confirmTicketAppRequest);
        BaseResponse baseResponse = restTemplate.postForObject(LMMApi.CONFIRM_TICKET_URL,confirmTicketRequest,BaseResponse.class);
        return baseResponse;
    }

    /**
     * 退票
     * @param returnTicketAppRequest
     * @return
     */
    public BaseResponse returnTicket(ReturnTicketAppRequest returnTicketAppRequest){
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.RETURN_TICKET_METHOD,LMMContant.MESSAGE_FORMT,LMMContant.CALL_BACK_URL+LMMContant.RETURN_TICKET_CALL_BACK_URL);
        ReturnTicketRequest returnTicketRequest = DozerUtils.map(baseRequest,ReturnTicketRequest.class);
        returnTicketRequest.setData(returnTicketAppRequest);
        BaseResponse baseResponse = restTemplate.postForObject(LMMApi.RETURN_TICKET_URL,returnTicketRequest,BaseResponse.class);
        return baseResponse;
    }

    /**
     *  查询订单详情
     * @param orderDetailAppRequest
     * @return
     */
    public OrderDetailResponse queryOrderDetail(OrderDetailAppRequest orderDetailAppRequest){
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.QUERY_ORDER_DETAIL_METHOD,LMMContant.MESSAGE_FORMT,"");
        OrderDetailRequest orderDetailRequest = DozerUtils.map(baseRequest,OrderDetailRequest.class);
        orderDetailRequest.setData(orderDetailAppRequest);
        OrderDetailResponse orderDetailResponse = restTemplate.postForObject(LMMApi.QUERY_ORDER_DETAIL_URL,orderDetailRequest,OrderDetailResponse.class);
        return orderDetailResponse;
    }

    /**
     * 订单改签
     * @param changeOrderAppRequest
     * @return
     */
    public OrderDetailResponse changeTicket(ChangeOrderAppRequest changeOrderAppRequest){
        //请求驴妈妈接口
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.CHANGE_TICKET_METHOD,LMMContant.MESSAGE_FORMT,LMMContant.CALL_BACK_URL+LMMContant.CHANGE_TICKET_CALL_BACK_URL);
        ChangeOrderRequest changeOrderRequest = DozerUtils.map(baseRequest,ChangeOrderRequest.class);
        changeOrderRequest.setData(changeOrderAppRequest);
        OrderDetailResponse orderDetailResponse = restTemplate.postForObject(LMMApi.CHANGE_TICKET_URL,changeOrderRequest,OrderDetailResponse.class);
        //更改数据库
        TrainChangsDto trainChangsDto = DozerUtils.map(changeOrderAppRequest,TrainChangsDto.class);
        trainChangsDto.setCustomId(trainChangsDto.getPartnerOrderNo());
        trainChangsDto.setOrderId(trainChangsDto.getOrderNo());
        trainChangsService.createTrainChangs(trainChangsDto);
        //更改订单总表
        //TODO order服务还没有开启对火车票的支持
        OrderInfoRequest orderInfoRequest = new OrderInfoRequest();
        orderInfoRequest.setOrderId(changeOrderAppRequest.getPartnerOrderNo());
        orderInfoRequest.setMinStatus(1);
        orderInfoRequest.setMaxStatus(1);
        orderInfoRequest.setCarStatus(1);
        orderApi.update(null,orderInfoRequest);
        return orderDetailResponse;
    }

    /**
     * 线下退款
     * @param orderOfflineRefundAppRequest
     * @return
     */
    public BaseResponse offlineRefund(OrderOfflineRefundAppRequest orderOfflineRefundAppRequest){
        BaseRequest baseRequest = basePushUtil.push(LMMContant.APP_KEY,LMMContant.OFFLINE_REFUND_METHOD,LMMContant.MESSAGE_FORMT,"");
        OrderOfflineRefundRequest orderOfflineRefundRequest = DozerUtils.map(baseRequest,OrderOfflineRefundRequest.class);
        orderOfflineRefundRequest.setData(orderOfflineRefundAppRequest);
        BaseResponse baseResponse = restTemplate.postForObject(LMMApi.CHANGE_TICKET_URL,orderOfflineRefundRequest,BaseResponse.class);
        return baseResponse;
    }



    private TrainOrderDto requestToDto(OrderBookingAppRequest orderBookingAppRequest) {
        TrainOrderDto trainOrderDto = DozerUtils.map(orderBookingAppRequest.getOrderBookingInfo(), TrainOrderDto.class);
        TrainOrderDto trainOrderDto2 = DozerUtils.map(orderBookingAppRequest,TrainOrderDto.class);
        trainOrderDto.setExpressInfo(trainOrderDto2.getExpressInfo());

        // TODO 对保险的封装
        /*List<InsuranceInfoAppRequest> insuranceVos = orderBookingAppRequest.getInsuranceVos();
        List<TrainPassengerDto> orderBookingPassengerVos = trainOrderDto.getOrderBookingPassengerVos();
        for (TrainPassengerDto trainPassengerDto:orderBookingPassengerVos){
            for (InsuranceInfoAppRequest insuranceInfoAppRequest:insuranceVos){
                TrainInsuranceDto map = DozerUtils.map(insuranceInfoAppRequest, TrainInsuranceDto.class);
                trainPassengerDto.getInsuranceVos().add(map);
            }
        }*/
        return trainOrderDto;
    }
}
